/**
 * weapp-js v1.7.1(2021-4-16)
 * https://codeup.aliyun.com/motigo/motigo/weapp_base
 * Copyright@ 2021 Motigo, Inc.
 * 
 */
/*
    模块功能：
        接管touchstart touchmove touchend三个事件，保护安卓系统任务栏下拉导致touchend无法触发问题

    使用示例：
        <touch-guard catchtouchstart="beginTouchRecord" catchtouchmove="onTouchRecordMove" catchtouchend="endTouchRecord">
            <!-- 需要长按的元素内容 -->
        </touch-guard>

        示例说明：
            将原本需要长按的内容放在<touch-guard>组件内部，监听<touch-guard>组件的touchstart touchmove touchend三个事件，由<touch-guard>组件保证touchend触发的必然性
*/
function getCurrentSecond(){
    /*
        返回当前时间戳，以秒为单位
    */
    return Math.floor(new Date().getTime() / 1000)
}

class touchEventMonitor {
    /*
        长按事件状态管理：主要是为了防止在安卓上，任务栏下拉导致touchend事件不触发问题

        解决策略是：
            监听touchmove事件，1s检测一次，如果没有连续触发touchmove事件，则表示touchend事件被取消
    */
    constructor(){
        this.start = null;
        this.data = {}
        this.end = null;
        this.tid = null
        Object.defineProperty(this,"ENUM",{
            configurable: false,
            writable: false,
            enumerable: true,
            value:Object.freeze({
                "NOTSTART":"NOTSTART",
                "TOUCHING":"TOUCHING",
                "TOUCHEND":"TOUCHEND"
            })
        })
        this.state = this.ENUM.NOTSTART
    }
    listen(){
        /*
            开始监听touchmove事件是否连续触发
        */
        return new Promise((resolve,reject)=>{
            false && reject;
            this.start = getCurrentSecond()
            this.state = this.ENUM.TOUCHING
            this.clearMonitorTask()
            this.tid = setInterval(()=>{
                let now = getCurrentSecond()
                let previous = now - 1;
                if(previous > this.start && this.data[previous] == undefined && this.state !== this.ENUM.TOUCHEND){
                    resolve && resolve()
                    this.cancel()
                }
            },1000)
        })
    }
    traceMove(){
        /*
            记录每一次touchmove触发
        */
        let sec = getCurrentSecond()
        if(this.data[sec] == undefined){
            this.data[sec] = 0
        }
        // 统计每一秒以内连续触发的次数
        this.data[sec] ++;
    }
    cancel(){
        /*
            取消监听计划
        */
        this.clearMonitorTask()
        this.state = this.ENUM.TOUCHEND
    }
    clearMonitorTask(){
        /*
            清除监听任务
        */
        if(this.tid){
            clearInterval(this.tid)
            this.tid = null
        }
    }
}

Component({
    data: {},
    methods:{
        touchBegin(evt){
            /*
                用户touch开始
            */
            // 启动监听计划
            this.monitor = new touchEventMonitor()
            this.monitor.listen().then(()=>{
                // 监听发现touchmove不再连续触发，通知调用方touch结束
                this.triggerEvent("touchend",this.lastMoveData || {})  
            })
            // 向调用方转发touchstart事件
            this.triggerEvent("touchstart",evt)
        },
        touchMove(evt){
            this.lastMoveData = evt;
            // 统计touchmove数据
            this.monitor && this.monitor.traceMove()
            // 向调用方转发touchmove事件
            this.triggerEvent("touchmove",evt)
        },
        touchEnd(evt){
            /*
                用户touch结束
            */
            // 取消监听计划
            this.monitor && this.monitor.cancel()
            // 向调用方转发touchend事件
            this.triggerEvent("touchend",evt)
        }
    }
})